﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;
using CharacterTrailClient.Windows;
using DevExpress.LookAndFeel;
using DevExpress.Utils;
using DevExpress.Utils.Menu;
using DevExpress.XtraBars.Docking;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Menu;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.XtraTreeList;

namespace CharacterTrailClient.Style
{
    /// <summary>
    /// GridControl、TreeList布局
    /// </summary>
    public static class LayoutHelper
    {
        private const string DefaultDirectory = @"\defaultStyle\";
        private const string LayoutDirectory = @"\Layout\";
        const string SetFontTag = "设置字体";
        const string DefaultFontTag = "还原默认字体";
        const string RestoreDefaultLayout = "还原默认列风格";
        const string OutExcelTag = "导出Excel";
        #region GridControl
        /// <summary>
        /// 加载GridControl布局
        /// </summary>
        /// <param name="grid">GridControl Object</param>
        public static void LoadGridLayout(GridControl grid)
        {
            try
            {
                InitMenu(grid);

                string baseDir = Application.StartupPath + LayoutDirectory;
                string defaultDir = baseDir + DefaultDirectory;
                if ((grid as Control).FindForm() is FormBase)
                {
                    string user = ((grid as Control).FindForm() as FormBase).OpenThisFormUserId;
                    baseDir = baseDir + user + @"\";
                }
                else
                {
                    return;
                }

                //1，先写下默认的风格文件
                string defaultLayoutFile = string.Format("{0}{1}.{2}.layout", defaultDir, grid.FindForm().GetType().FullName, grid.Name);
                if (!Directory.Exists(defaultDir))
                {
                    Directory.CreateDirectory(defaultDir);
                }
                grid.DefaultView.SaveLayoutToXml(defaultLayoutFile, OptionsLayoutBase.FullLayout);

                string layoutFile = string.Format("{0}{1}.{2}.layout", baseDir, grid.FindForm().GetType().FullName, grid.Name);
                if (System.IO.File.Exists(layoutFile))
                {
                    //加载布局
                    grid.DefaultView.RestoreLayoutFromXml(layoutFile, OptionsLayoutBase.FullLayout);
                }
            }
            catch { }
        }

        #region 菜单
        private static void InitMenu(GridControl grid)
        {
            if (grid.ContextMenuStrip != null)
            {
                if (grid.ContextMenuStrip.Items.ContainsKey(SetFontTag))
                {
                    return;
                }
                ToolStripItem menuSetFontTag = new ToolStripMenuItem();
                ToolStripItem menuDefaultFontTag = new ToolStripMenuItem();
                ToolStripItem menuRestoreDefaultLayoutTag = new ToolStripMenuItem();
                ToolStripItem menuOutExcelTag = new ToolStripMenuItem();

                menuSetFontTag.Image = GridMenuImages.Column.Images[3];
                menuSetFontTag.Text = SetFontTag;
                menuSetFontTag.Name = SetFontTag;
                menuDefaultFontTag.Image = GridMenuImages.Column.Images[2];
                menuDefaultFontTag.Text = DefaultFontTag;
                menuDefaultFontTag.Name = DefaultFontTag;
                menuRestoreDefaultLayoutTag.Image = GridMenuImages.Column.Images[7];
                menuRestoreDefaultLayoutTag.Text = RestoreDefaultLayout;
                menuRestoreDefaultLayoutTag.Name = RestoreDefaultLayout;
                menuOutExcelTag.Image = GridMenuImages.Column.Images[0];
                menuOutExcelTag.Text = OutExcelTag;
                menuOutExcelTag.Name = OutExcelTag;

                #region register events
                menuSetFontTag.Click += (sender, e) => SetFont(grid);

                menuDefaultFontTag.Click += (sender, e) => DefaultFont(grid);

                menuRestoreDefaultLayoutTag.Click += (sender, e) => DoRestoreDefaultLayout(grid);

                menuOutExcelTag.Click += (sender, e) => OutExcel(grid);
                #endregion

                grid.ContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
                    menuSetFontTag,
                    menuDefaultFontTag,
                    menuRestoreDefaultLayoutTag,
                    menuOutExcelTag});
            }
            else
            {
                if (grid.ContextMenu != null)
                {
                    if (grid.ContextMenu.MenuItems.ContainsKey(SetFontTag))
                    {
                        return;
                    }
                    var menuSetFontTag = new MenuItem();
                    var menuDefaultFontTag = new MenuItem();
                    var menuRestoreDefaultLayoutTag = new MenuItem();
                    var menuOutExcelTag = new MenuItem();

                    menuSetFontTag.Text = SetFontTag;
                    menuSetFontTag.Name = SetFontTag;
                    menuDefaultFontTag.Text = DefaultFontTag;
                    menuDefaultFontTag.Name = DefaultFontTag;
                    menuRestoreDefaultLayoutTag.Text = RestoreDefaultLayout;
                    menuRestoreDefaultLayoutTag.Name = RestoreDefaultLayout;
                    menuOutExcelTag.Text = OutExcelTag;
                    menuOutExcelTag.Name = OutExcelTag;

                    #region register events
                    menuSetFontTag.Click += (sender, e) => SetFont(grid);

                    menuDefaultFontTag.Click += (sender, e) => DefaultFont(grid);

                    menuRestoreDefaultLayoutTag.Click += (sender, e) => DoRestoreDefaultLayout(grid);

                    menuOutExcelTag.Click += (sender, e) => OutExcel(grid);
                    #endregion

                    grid.ContextMenu.MenuItems.AddRange(new MenuItem[] { menuSetFontTag,
                    menuDefaultFontTag,
                    menuRestoreDefaultLayoutTag,
                    menuOutExcelTag});
                }
                else
                {
                    grid.MouseDown += delegate(object sender, MouseEventArgs e)
                    {
                        var gc = sender as GridControl;
                        if (e.Button == MouseButtons.Right)
                        {
                            ShowMenu(gc, ((GridView)gc.MainView).CalcHitInfo(new System.Drawing.Point(e.X, e.Y)));
                        }
                    };
                }
            }
        }

        private static void ShowMenu(GridControl gc, GridHitInfo ghi)
        {
            GridViewMenu menu = null;
            if (ghi.HitTest == GridHitTest.ColumnButton)
            {
                menu = new GridViewColumnButtonMenu((GridView)gc.MainView);
                menu.Init(ghi);
                menu.Show(ghi.HitPoint);
            }
        }

        private class GridViewColumnButtonMenu : GridViewMenu
        {
            internal GridViewColumnButtonMenu(DevExpress.XtraGrid.Views.Grid.GridView view) : base(view) { }
            protected override void CreateItems()
            {
                Items.Clear();
                Items.Add(CreateMenuItem(SetFontTag, GridMenuImages.Column.Images[3], SetFontTag, true));
                Items.Add(CreateMenuItem(DefaultFontTag, GridMenuImages.Column.Images[2], DefaultFontTag, true));
                Items.Add(CreateMenuItem(RestoreDefaultLayout, GridMenuImages.Column.Images[7], RestoreDefaultLayout, true));
                Items.Add(CreateMenuItem(OutExcelTag, GridMenuImages.Column.Images[0], OutExcelTag, true));
            }

            protected override void OnMenuItemClick(object sender, EventArgs e)
            {
                if (RaiseClickEvent(sender, null)) return;
                var item = sender as DXMenuItem;
                if (item.Tag == null) return;
                if (item.Tag.ToString() == SetFontTag)
                {
                    SetFont(View.GridControl);
                }
                else if (item.Tag.ToString() == DefaultFontTag)//设置默认字体
                {
                    DefaultFont(View.GridControl);
                }
                else if (item.Tag.ToString() == RestoreDefaultLayout)//编辑列名
                {
                    DoRestoreDefaultLayout(View.GridControl);
                }
                else if (item.Tag.ToString() == OutExcelTag)//导出excel
                {
                    OutExcel(View.GridControl);
                }
            }
        }

        #region 静态工作函数

        private static void SetFont(GridControl gc)
        {
            var gv = gc.MainView as GridView;
            var dlg = new FontDialog();
            dlg.Font = gv.Appearance.Row.Font;
            dlg.FontMustExist = true;
            dlg.ShowColor = false;
            dlg.ShowApply = false;
            dlg.MaxSize = 48;

            if (dlg.ShowDialog() != DialogResult.Cancel)
            {
                gv.Appearance.FooterPanel.Font = dlg.Font;
                gv.Appearance.FooterPanel.Options.UseFont = true;
                gv.Appearance.GroupFooter.Font = dlg.Font;
                gv.Appearance.GroupFooter.Options.UseFont = true;
                gv.Appearance.HeaderPanel.Font = dlg.Font;
                gv.Appearance.HeaderPanel.Options.UseFont = true;
                gv.Appearance.Row.Font = dlg.Font;
                gv.Appearance.Row.Options.UseFont = true;
            }
        }

        private static void DoRestoreDefaultLayout(GridControl gc)
        {
            var gridView = (GridView)gc.MainView;
            string baseDir = Application.StartupPath + LayoutDirectory;
            string defaultDir = baseDir + DefaultDirectory;
            string defaultLayoutFile = string.Format("{0}{1}.{2}.layout", defaultDir, (gc as Control).FindForm().GetType().FullName, gc.Name);
            gc.DefaultView.RestoreLayoutFromXml(defaultLayoutFile, OptionsLayoutBase.FullLayout);
        }

        private static void DefaultFont(GridControl gc)
        {
            ((GridView)gc.MainView).Appearance.Reset();
        }

        private static void OutExcel(GridControl gc)
        {
            string path = Application.StartupPath + "\\outexcel\\";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            string excelFile = path + (gc as Control).FindForm().GetType().FullName + "." + gc.Name + ".xls";

            try
            {
                if (File.Exists(excelFile))
                {
                    File.Delete(excelFile);
                }
                gc.ExportToXls(excelFile);
                Process.Start(excelFile);
            }
            catch (Exception ex)
            {
                MessageBox.Show(@"请关掉excel，重新导出！\n\r" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        #endregion

        #endregion

        /// <summary>
        /// 存储GridControl布局
        /// </summary>
        /// <param name="grid">GridControl Object</param>
        public static void SaveGridLayout(GridControl grid)
        {
            try
            {
                string baseDir = Application.StartupPath + LayoutDirectory;

                if ((grid as Control).FindForm() is FormBase)
                {
                    string user = ((grid as Control).FindForm() as FormBase).OpenThisFormUserId;
                    baseDir = baseDir + user + @"\";
                }
                else
                {
                    return;
                }

                string file = baseDir + (grid as Control).FindForm().GetType().FullName + "." + grid.Name + ".layout";
                if (!System.IO.Directory.Exists(baseDir))
                    System.IO.Directory.CreateDirectory(baseDir);

                //以下代码是清除过滤器，清除分组，清除排序，以免这些信息记录到样式文件中。
                var gv = grid.DefaultView as GridView;
                gv.ClearColumnsFilter();
                gv.ClearGrouping();
                gv.ClearSorting();

                grid.DefaultView.SaveLayoutToXml(file, DevExpress.Utils.OptionsLayoutBase.FullLayout);
            }
            catch { }
        }
        #endregion GridControl

        #region TreeList
        /// <summary>
        /// 加载TreeList布局
        /// </summary>
        /// <param name="tree">TreeList Object</param>
        /// <param name="UserStyle">风格：true-用户 false-默认风格</param>
        public static void LoadTreeListLayout(TreeList tree, bool UserStyle)
        {
            try
            {
                string dir = Application.StartupPath + LayoutDirectory;
                if (UserStyle)
                {
                    if ((tree as Control).FindForm() is FormBase)
                    {
                        string user = ((tree as Control).FindForm() as FormBase).OpenThisFormUserId;
                        dir = dir + @"\" + user + @"\";
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    dir = dir + DefaultDirectory;
                }
                string layoutFile = dir + (tree as Control).FindForm().GetType().FullName + "." + tree.Name + ".layout";
                if (System.IO.File.Exists(layoutFile))
                {
                    string dllFile = (tree as Control).FindForm().GetType().Assembly.Location;
                    if (System.IO.File.Exists(dllFile))
                    {
                        DateTime dllTime = System.IO.File.GetLastWriteTime(dllFile);
                        DateTime layoutTime = System.IO.File.GetLastWriteTime(layoutFile);
                        if (dllTime > layoutTime)
                            return;
                    }
                    tree.RestoreLayoutFromXml(layoutFile);
                }
            }
            catch { }
        }
        /// <summary>
        /// 存储TreeList布局
        /// </summary>
        /// <param name="tree">TreeList Object</param>
        /// <param name="UserStyle">风格：true-用户 false-默认风格</param>
        public static void SaveTreeListLayout(TreeList tree, bool UserStyle)
        {
            try
            {
                string dir = Application.StartupPath + LayoutDirectory;
                if (UserStyle)
                {
                    if ((tree as Control).FindForm() is FormBase)
                    {
                        string user = ((tree as Control).FindForm() as FormBase).OpenThisFormUserId;
                        dir = dir + @"\" + user + @"\";
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    dir = dir + DefaultDirectory;
                }
                string file = dir + (tree as Control).FindForm().GetType().FullName + "." + tree.Name + ".layout";
                if (!System.IO.Directory.Exists(dir))
                    System.IO.Directory.CreateDirectory(dir);
                tree.SaveLayoutToXml(file);
            }
            catch { }
        }
        #endregion TreeList

        #region DockManager
        /// <summary>
        /// 加载DockManager布局
        /// </summary>
        /// <param name="dockm">DockManager Object</param>
        public static void LoadDockManagerLayout(DockManager dockm, string Name)
        {
            try
            {
                string dllFile = dockm.Form.GetType().Assembly.Location;
                string layoutFile = Application.StartupPath + LayoutDirectory + dockm.Form.GetType().FullName + "." + Name + ".layout";
                if (System.IO.File.Exists(layoutFile))
                {
                    if (System.IO.File.Exists(dllFile))
                    {
                        DateTime dllTime = System.IO.File.GetLastWriteTime(dllFile);
                        DateTime layoutTime = System.IO.File.GetLastWriteTime(layoutFile);
                        if (dllTime > layoutTime)
                            return;
                    }
                    dockm.RestoreLayoutFromXml(layoutFile);
                }
            }
            catch { }
        }
        /// <summary>
        /// 存储DockManager布局
        /// </summary>
        /// <param name="dockm">TreeList Object</param>
        public static void SaveDockManagerLayout(DockManager dockm, string Name)
        {
            try
            {
                string dir = Application.StartupPath + LayoutDirectory;
                string file = Application.StartupPath + LayoutDirectory + dockm.Form.GetType().FullName + "." + Name + ".layout";
                if (!System.IO.Directory.Exists(dir))
                    System.IO.Directory.CreateDirectory(dir);
                dockm.SaveLayoutToXml(file);
            }
            catch { }
        }
        #endregion DockManager

        #region LookAndFeel
        /// <summary>
        /// 保存系统外观
        /// </summary>
        /// <param name="look">系统外观变量</param>
        public static void SaveLookAndFeel(DefaultLookAndFeel look)
        {
            try
            {
                string feel = ((int)look.LookAndFeel.Style).ToString() + "," + look.LookAndFeel.SkinName;
                string file = Application.StartupPath + LayoutDirectory + "DefaultLookAndFeel.data";
                using (StreamWriter sw = new StreamWriter(file))
                {
                    sw.Write(feel);
                }
            }
            catch { }
        }
        /// <summary>
        /// 加载系统外观
        /// </summary>
        /// <param name="look">系统外观变量</param>
        public static void LoadLookAndFeel(DefaultLookAndFeel look)
        {
            try
            {
                string file = Application.StartupPath + LayoutDirectory + "DefaultLookAndFeel.data";
                using (StreamReader sr = new StreamReader(file))
                {
                    string[] feel = sr.ReadToEnd().Split(',');
                    look.LookAndFeel.Style = (DevExpress.LookAndFeel.LookAndFeelStyle)int.Parse(feel[0]);
                    look.LookAndFeel.SkinName = feel[1];
                }
            }
            catch { }
        }
        #endregion LookAndFeel
    }
}
